#ifndef __INposixh
#define __INposixh

#ifndef FMT_POSIX
    #if defined(_WIN32) && !defined(__MINGW32__)
        #define FMT_POSIX(call) _##call
    #else
        #define FMT_POSIX(call) ::call
    #endif
#endif

// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
    #define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
    #define FMT_POSIX_CALL(call) FMT_POSIX(call)
#endif

#ifdef _WIN32
    #define _LIKELY(x)			(x)
    #define _UNLIKELY(x)		(x)
    #define	STDIN_FILENO	    0	/* Standard input.  */
    #define	STDOUT_FILENO	    1	/* Standard output.  */
    #define	STDERR_FILENO	    2	/* Standard error output.  */
#else
    #define _LIKELY(x)			__builtin_expect((long)!!(x), 1L)
    #define _UNLIKELY(x)		__builtin_expect((long)!!(x), 0L)
#endif

#ifdef __cplusplus
    #define EXTERN_C_BEGIN extern "C" {
    #define EXTERN_C_END   }
    #define EXTERN_C       extern "C"
#else
    #define EXTERN_C_BEGIN
    #define EXTERN_C_END
    #define EXTERN_C
#endif

EXTERN_C_BEGIN
    typedef int (*FUNCPTR)(...);      /* ptr to function returning int */
    typedef void (*VOIDFUNCPTR)(...); /* ptr to function returning void */
EXTERN_C_END

/* A new builtin version of OFFSET() that also complies with Misra-c 20.7 rule */

#define OFFSET(structure, member) \
    ((long)(__builtin_offsetof(structure, member)))

/* size of a member of a structure */
#define MEMBER_SIZE(structure, member) (sizeof(((structure *)0)->member))

/* number of elements in an array */
#define NELEMENTS(array) (sizeof(array) / sizeof((array)[0]))

#define FOREVER for (;;)

#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) ); })

#define ROUND_UP_UL(x, align) (((unsigned long)(x) +            \
                                ((unsigned long)align - 1UL)) & \
                               ~((unsigned long)align - 1UL))
#define ROUND_DOWN_UL(x, align) ((unsigned long)(x) & \
                                 ~((unsigned long)align - 1UL))
#define ALIGNED_UL(x, align) (((unsigned long)(x) & ((unsigned long)align - 1UL)) == 0)

#define ROUND_UP_ULL(x, align) (((unsigned long long)(x) +             \
                                 ((unsigned long long)align - 1ULL)) & \
                                ~((unsigned long long)align - 1ULL))
#define ROUND_DOWN_ULL(x, align) ((unsigned long long)(x) & \
                                  ~((unsigned long long)align - 1ULL))
#define ALIGNED_ULL(x, align) (((unsigned long long)(x) & \
                                ((unsigned long long)align - 1ULL)) == 0)

#define ROUND_UP ROUND_UP_UL
#define ROUND_DOWN ROUND_DOWN_UL
#define ALIGNED ALIGNED_UL

#endif
